package action;

import java.io.ByteArrayInputStream;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.regex.Pattern;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.json.JSONObject;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;

import bean.Lucky;
import bean.User;
import bean.UserRank;
import service.DepositService;
import service.LuckyService;
import service.SupportService;
import service.UserService;
import utils.AjaxResult;
import utils.AppConfig;
import utils.DateTimeUtils;
import utils.HttpRequest;
import utils.HttpsRequest;
import utils.MailUtils;
import utils.PagingParams;
import utils.PhoneUtils;

public class UserAction extends BaseAction {

    private String phone;
    private String userName;
    private String code;
    private String tag;
    private String openId;
    private String avatar;
    private String candidate;
    private String supporter;
    
    private String currentPage;
    private String queryKey;
    
    
    private static final String MOB_SMS_SEND_CODE_URL = "https://api.sms.mob.com/sms/sendmsg";
    private static final String MOB_SMS_CHECK_CODE_URL = "https://api.sms.mob.com/sms/checkcode";
    private static final String GET_BELONG_URL = "http://life.tenpay.com/cgi-bin/mobile/MobileQueryAttribution.cgi";
    
    private UserService userService;
    private LuckyService luckyService;
    private SupportService supportService;
    private DepositService depositService;
    
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    
    public void setLuckyService(LuckyService luckyService) {
        this.luckyService = luckyService;
    }
    
    public void setSupportService(SupportService supportService) {
        this.supportService = supportService;
    }
    
    public void setDepositService(DepositService depositService) {
        this.depositService = depositService;
    }
    
    public String cardAdded() {
        AjaxResult result = null;
        if (isNullOrEmptyString(openId)) {
            result = new AjaxResult(AjaxResult.CODE_ERROR, "error, no openId");
        } else {
            luckyService.updateStatus(openId.trim(), Lucky.STATUS_GET);
            result = new AjaxResult(AjaxResult.CODE_SUCCESS, "success");
        }
        
        try {
            inputStream = new ByteArrayInputStream(result.toString().getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        
        return SUCCESS;
    }
    
    public String rank() {
        int page;
        if (currentPage == null) {
            currentPage = "1";
        }
        
        try {
            page = Integer.parseInt(currentPage);
        } catch (NumberFormatException e) {
            page = 1; // 默认值1
        }
        
        if ((queryKey != null && "".equals(queryKey.trim())) || queryKey == null)
            queryKey = "";
        List<UserRank> list = null;
        int total = 0;
        
        // 获取数据
        list = userService.query(queryKey, PagingParams.COUNTS_PER_PAGE, 
                (page - 1) * PagingParams.COUNTS_PER_PAGE);
        total = userService.queryCount(queryKey);
        
        // 在session中记录参数
        session.setAttribute(PagingParams.PAGING_RESULT_AJAX_RESULT, UserRank.toJSONArray(list).toString());
        session.setAttribute(PagingParams.RESULT_SET_TOTAL_SIZE, total);
        session.setAttribute(PagingParams.PAGING_SOURCE, PagingParams.PAGING_SOURCE_RANK);
        session.setAttribute(PagingParams.CURRENT_PAGE, page);
        session.setAttribute(PagingParams.PAGING_PARAM_COUNTS_PER_PAGE, 
                PagingParams.COUNTS_PER_PAGE);
        session.setAttribute(PagingParams.EXTRA_REQUEST_PARAMS, "queryKey=" + queryKey);
        
        return SUCCESS;
    }
    
    /**
     * 投票
     * @return
     */
    public String support() {
        AjaxResult result = null;
        if (isNullOrEmptyString(candidate) || isNullOrEmptyString(supporter)) {
            result = new AjaxResult(AjaxResult.CODE_ERROR, "缺少鼓劲相关信息");
        } else {
            // 尝试投票
            int code = supportService.support(supporter.trim(), candidate.trim());
            if (code == SupportService.SUPPORT_SUCCESS) {
                result = new AjaxResult(AjaxResult.CODE_SUCCESS, "success");
            } else {
                result = new AjaxResult(AjaxResult.CODE_ERROR, "每人每天最多鼓3次劲哦~ 欢迎明天再来~");
            }
        }
        
        try {
            inputStream = new ByteArrayInputStream(result.toString().getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        
        return SUCCESS;
    }
    
    /**
     * 获取候选者个人信息
     * @return
     */
    public String candidateInfo() {
        AjaxResult result = null;
        if (isNullOrEmptyString(candidate)) {
            result = new AjaxResult(AjaxResult.CODE_ERROR, "缺少候选者信息，2秒后跳转到首页");
            result.addData("noCandidate", "true");
        } else {
            // get user
            User user = userService.getByOpenId(candidate.trim());
            if (user == null) {
                result = new AjaxResult(AjaxResult.CODE_ERROR, "没有该候选者的相关信息，2秒后跳转到首页");
                result.addData("noCandidate", "true");
            } else {
                result = new AjaxResult(AjaxResult.CODE_SUCCESS, "success");
                result.addData("avatar", user.getAvatar());
                result.addData("openId", user.getOpenId());
                result.addData("phone", PhoneUtils.hideCentralNum(user.getPhone()));
                result.addData("support", user.getSupport());
                result.addData("tag", user.getTag());
                result.addData("userId", user.getUserId());
                result.addData("userName", user.getUserName());
                result.addData("rank", userService.getRank(user.getSupport()));
            }
        }
        
        try {
            inputStream = new ByteArrayInputStream(result.toString().getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        
        return SUCCESS;
    }
    
    /**
     * 抽奖
     * @return
     */
    public String draw() {
        //TODO 测试用，记得删掉------------------------
        //新建卡券
//        depositService.buildNewCard();
        //导入指定code
//        depositService.importDepositCode("1861056");
        //批量导入code
//        depositService.importDepositCode(5000);
        //获取已导入的code数目
//        System.out.println("获取已导入的code数目"+depositService.getDepositCount());
        
        //更新库存
//        System.out.println("更改卡券库存");
//        depositService.updateCardCount();
        //查看卡券详情
//        net.sf.json.JSONObject cardDetail = depositService.getCardDetail();
//        System.out.println("返回卡券详情接口返回的数据为：" + cardDetail.toString());
        //设置测试白名单
//        depositService.setTestWhiteList();
        //核查code
//        depositService.checkCode();
        
//        openId = "ol-ZLt42QCylIQbUXxUsUFEAvVCU";
        //更改卡券详情
//        depositService.updateCardInfo();
        
        AjaxResult result = null;
        if (isNullOrEmptyString(openId)) {
            result = new AjaxResult(AjaxResult.CODE_ERROR, "缺少微信账号信息，2秒后跳转到首页");
            result.addData("noOpenId", true);
        } else {
            // get user
            User user = userService.getByOpenId(openId.trim());
            if (user == null) {
                result = new AjaxResult(AjaxResult.CODE_ERROR, "该微信账号尚未报名，2秒后跳转到首页");
                result.addData("notRegistered", true);
            } else {
                Lucky existLucky = luckyService.getDrawed(openId.trim());
                if (existLucky != null) {
                    result = new AjaxResult(AjaxResult.CODE_ERROR, "您已经抽过奖啦");
                    result.addData("hasDrawed", true);
                    result.addData("level", existLucky.getLevel());
                    result.addData("status", existLucky.getStatus());
                } else {
                    int level = luckyService.draw(openId);
                    System.out.println("抽中的是"+level);
                    // 发送邮件通知
                    if (level == Lucky.LEVEL_FIRST || level == Lucky.LEVEL_SECOND) {
                        Lucky lucky = luckyService.getByOpenId(openId.trim());
                        StringBuilder subBuilder = new StringBuilder();
                        subBuilder.append(level == Lucky.LEVEL_FIRST ? "一等奖" : "二等奖")
                            .append("-").append(user.getPhone()).append("-").append(user.getUserName());
                        StringBuilder contentBuilder = new StringBuilder();
                        contentBuilder.append("姓名：").append(user.getUserName()).append("\r\n")
                            .append("手机号：").append(user.getPhone()).append("\r\n")
                            .append("奖品：").append(level == Lucky.LEVEL_FIRST ? "一等奖" : "二等奖").append("\r\n");
                        if (lucky != null) {
                            contentBuilder.append("抽奖时间：" + DateTimeUtils.generateDateTimeString(lucky.getLuckyTime()));
                        }
                        System.out.println("发邮件");   
                        MailUtils.send("jingjiupinpai@163.com", subBuilder.toString(), contentBuilder.toString());
                    }
                    
                    result = new AjaxResult(AjaxResult.CODE_SUCCESS, "success");
                    result.addData("level", level);
                    System.out.println("draw result="+result.toString());
                }
            }
        }
        
        try {
            inputStream = new ByteArrayInputStream(result.toString().getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        
        return SUCCESS;
    }

    /**
     * 获取用户信息
     * 基本信息&是否已抽过奖
     * @return
     */
    public String user() {
        AjaxResult result = null;
        if (isNullOrEmptyString(openId)) {
            result = new AjaxResult(AjaxResult.CODE_ERROR, "缺少微信账号信息，2秒后跳转到首页");
            result.addData("noOpenId", "true");
        } else {
            // get user
            User user = userService.getByOpenId(openId.trim());
            if (user == null) {
                result = new AjaxResult(AjaxResult.CODE_ERROR, "该微信账号尚未报名，2秒后跳转到首页");
                result.addData("notRegistered", "true");
            } else {
                result = new AjaxResult(AjaxResult.CODE_SUCCESS, "success");
                result.addData("avatar", user.getAvatar());
                result.addData("openId", user.getOpenId());
                result.addData("phone", PhoneUtils.hideCentralNum(user.getPhone()));
                result.addData("support", user.getSupport());
                result.addData("tag", user.getTag());
                result.addData("userId", user.getUserId());
                result.addData("userName", user.getUserName());
                
                Lucky lucky = luckyService.getByOpenId(openId.trim());
                if (lucky == null) {
                    result.addData("lucky", false);
                } else {
                    result.addData("lucky", true);
                    result.addData("level", lucky.getLevel());
                    result.addData("luckyId", lucky.getLuckyId());
                    result.addData("luckyTime", lucky.getLuckyTime().getTime());
                    result.addData("openId", lucky.getOpenId());
                    result.addData("status", lucky.getStatus());
                }
            }
        }
        
        try {
            inputStream = new ByteArrayInputStream(result.toString().getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        
        return SUCCESS;
    }
    
    /**
     * 注册（报名）
     * @return
     */
    public String register() {
        //TODO 测试，记得删掉
//        openId = "ol-ZLt42QCylIQbUXxUsUFEAvVCY";
//        phone = "18610566426";
//        userName = "WP";
//        tag = "1";
//        code = "1234";
                
        AjaxResult result = null;
        if (isNullOrEmptyString(openId)) {
            // 没有微信账号信息
            result = new AjaxResult(AjaxResult.CODE_ERROR, "缺少微信账号信息，请刷新重试");
        } else if (isNullOrEmptyString(userName) || isNullOrEmptyString(phone) || isNullOrEmptyString(tag) || isNullOrEmptyString(code)) {
            // 缺少关键信息
            result = new AjaxResult(AjaxResult.CODE_ERROR, "缺少关键信息（用户名/手机号/标签），请刷新重试");
        } else {
            // 验证
            
            // 构造验证参数
            StringBuilder builder = new StringBuilder();
            builder.append("appkey=").append(AppConfig.MOB_APP_KEY).append("&")
                    .append("phone=").append(phone.trim()).append("&")
                    .append("code=").append(code.trim()).append("&")
                    .append("zone=86");
            // 验证验证码，获取返回结果
            String checkCodeResponse = null;
            try {
                checkCodeResponse = HttpsRequest.sendGet(MOB_SMS_CHECK_CODE_URL, builder.toString());
            } catch (Exception e) {
                checkCodeResponse = null;
            }
            
            // 处理返回结果
            if (checkCodeResponse == null) {
                // 验证失败
                result = new AjaxResult(AjaxResult.CODE_ERROR, "验证码服务器响应错误");
            } else {
                // 解析返回数据
                JSONObject obj = new JSONObject(checkCodeResponse);
                if (obj.has("status") && obj.getInt("status") == 200) {
                    // 尝试注册
                    // 获取归属地
                    String getBelongResponse = null;
                    String belong = "";
                    try{
                        getBelongResponse = HttpRequest.sendGet(GET_BELONG_URL, "chgmobile="+phone.trim()); 
//                        System.out.println("getBelongResponse = "+getBelongResponse.toString());
                    }catch(Exception e){
                        getBelongResponse = null;
                        e.printStackTrace();
                    }
                    if(getBelongResponse != null){
                        belong = parseBelongInfo(getBelongResponse.toString());
                    }
                       
                    else
                        belong = "未知";
                    System.out.println("belong="+belong);
                    User user = new User(openId.trim(), userName.trim(), phone.trim(),
                            (avatar != null) ? avatar.trim() : null, tag.trim(), 0, belong);
                    switch (userService.addUser(user)) {
                    case UserService.ADD_USER_SUCCESS:
                        result = new AjaxResult(AjaxResult.CODE_SUCCESS, "报名成功，2秒后将跳转");
//                        result.addData("hasDrawed", false);
                        break;
                    case UserService.ADD_USER_EXIST_OPEN_ID:
                        result = new AjaxResult(AjaxResult.CODE_SUCCESS, "该微信号已经报过名，2秒后将跳转");                        
                        break;
                    case UserService.ADD_USER_EXIST_PHONE:
                        result = new AjaxResult(AjaxResult.CODE_ERROR, "该手机号已经报过名，报名失败");
                        break;
                    default:
                        result = new AjaxResult(AjaxResult.CODE_ERROR, "报名失败");
                        break;
                    }
                } else {
                    result = new AjaxResult(AjaxResult.CODE_ERROR, "验证码错误");
                }
            }
        }
        
        try {
            inputStream = new ByteArrayInputStream(result.toString().getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        
        return SUCCESS;
    }
    
    private String parseBelongInfo(String data){
        System.out.println("data= "+data);
        String result = "";
        try{
            StringReader sr = new StringReader(data);
            InputSource is = new InputSource(sr);
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(is);
            String province = doc.getElementsByTagName("province").item(0).getTextContent();
            province = new String(province.getBytes("gb2312"),"utf-8");
            String city = doc.getElementsByTagName("city").item(0).getTextContent();
            city = new String(city.getBytes("gb2312"),"utf-8");
            System.out.println("province = "+province);
            System.out.println("city = "+city);
            result = province + " " + city;
        }catch(Exception e){
            result = "未知";
        }
        
        return result;
    }
    
    /**
     * 发送验证码
     * @return
     */
    public String sendCode() {
        AjaxResult result = null;
        if (isNullOrEmptyString(openId)) {
            // 没有微信账号信息
            result = new AjaxResult(AjaxResult.CODE_ERROR, "缺少微信账号信息，请刷新重试");
        } else if (userService.exists(openId.trim())) {
            // 已经报过名
            result = new AjaxResult(AjaxResult.CODE_ERROR, "该微信号已经报过名，2秒后将跳转");
            result.addData("exists", "true");
          //查看该用户是否已抽过奖
            Lucky existLucky = luckyService.getDrawed(openId.trim());
            if (existLucky != null) {
                result.addData("hasDrawed", true);                          
                result.addData("status", existLucky.getStatus());
            }
        } else if (isNullOrEmptyString(phone)) {
            // 没有手机号
            result = new AjaxResult(AjaxResult.CODE_ERROR, "请输入手机号");
        } else if (!Pattern.matches("^1[0-9]{10}", phone.trim())) {
            // 手机号格式验证失败
            result = new AjaxResult(AjaxResult.CODE_ERROR, "请输入11位手机号");
        } else if (userService.existsPhone(phone.trim())) {
            // 手机号已注册过
            result = new AjaxResult(AjaxResult.CODE_ERROR, "该手机号已经报过名，报名失败");
        } else {
            // 构造发送验证码参数
            StringBuilder builder = new StringBuilder();
            builder.append("appkey=").append(AppConfig.MOB_APP_KEY).append("&")
                    .append("phone=").append(phone.trim()).append("&")
                    .append("zone=86");
            
            // 发送验证码，获取返回结果
            String sendCodeResponse = null;
            try {
                sendCodeResponse = HttpsRequest.sendGet(MOB_SMS_SEND_CODE_URL, builder.toString());
            } catch (Exception e) {
                sendCodeResponse = null;
            }
            
            // 处理返回结果
            if (sendCodeResponse == null) {
                // 发送失败
                result = new AjaxResult(AjaxResult.CODE_ERROR, "验证码发送失败");
            } else {
                // 解析返回数据
                JSONObject obj = new JSONObject(sendCodeResponse);
                if (obj.has("status") && obj.getInt("status") == 200) {
                    result = new AjaxResult(AjaxResult.CODE_SUCCESS, "验证码发送成功");
                } else {
                    result = new AjaxResult(AjaxResult.CODE_ERROR, "验证码发送失败");
                }
            }
        }
        
        try {
            inputStream = new ByteArrayInputStream(result.toString().getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        
        return SUCCESS;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getTag() {
        return tag;
    }

    public void setTag(String tag) {
        this.tag = tag;
    }

    public String getOpenId() {
        return openId;
    }

    public String getSupporter() {
        return supporter;
    }

    public void setSupporter(String supporter) {
        this.supporter = supporter;
    }

    public void setOpenId(String openId) {
        this.openId = openId;
    }

    public String getAvatar() {
        return avatar;
    }

    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }

    public String getCandidate() {
        return candidate;
    }

    public void setCandidate(String candidate) {
        this.candidate = candidate;
    }

    public String getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(String currentPage) {
        this.currentPage = currentPage;
    }

    public String getQueryKey() {
        return queryKey;
    }

    public void setQueryKey(String queryKey) {
        this.queryKey = queryKey;
    }
    
}
